home *** CD-ROM | disk | FTP | other *** search
/ The Fatted Calf / The Fatted Calf.iso / Applications / Misc / a2 / Source / hgrconv.c < prev    next >
Encoding:
C/C++ Source or Header  |  1992-03-16  |  8.2 KB  |  299 lines

  1. #ifndef USE_COLOR
  2. #define USE_COLOR 1
  3. #endif
  4.  
  5. #include <c.h>
  6. #include <string.h>
  7. #include "hgrtable.h"
  8. #include "hgrconv.h"
  9.  
  10.  
  11. #if !USE_COLOR
  12. void
  13. apple_to_next (const unsigned char *a2buf, unsigned char nextbuf[192][72],
  14.            int first_row, int height)
  15. {
  16.   const unsigned int *row_base = row_to_addr + first_row;
  17.   unsigned long *nbuf = (unsigned long *) &nextbuf[first_row][0];
  18.   const unsigned char *p;
  19.   short rows_left, n;
  20.  
  21.   for (rows_left = height - 1; rows_left != -1; rows_left--)
  22.     {
  23.       p = a2buf + *row_base++;
  24.       for (n = 4; n != -1; n--)
  25.     {
  26. #if 0    /* Coerce compiler into using bitfield instructions.  Nonportable. */
  27.       /* Oddly enough, the shift-and-mask code below is faster, even
  28.        * though it's ~twice as many instructions.  The bitfield code
  29.            * performs 8 read-modify-writes as opposed to 4 writes.  Must be
  30.            * the difference.
  31.        * I'll leave this here cuz it looks cool...
  32.        */
  33.       void *buf = (void *) nbuf;
  34.  
  35.       ((struct { int a:14, b:14; } *) buf)->a      = one_to_two_bpp[*p++];
  36.       ((struct { int a:14, b:14; } *) buf)->b      = one_to_two_bpp[*p++];
  37.       ((struct { int a:12, b:14; } *) (buf+2))->b  = one_to_two_bpp[*p++];
  38.       ((struct { int a:10, b:14; } *) (buf+4))->b  = one_to_two_bpp[*p++];
  39.       ((struct { int a:8,  b:14; } *) (buf+6))->b  = one_to_two_bpp[*p++];
  40.       ((struct { int a:6,  b:14; } *) (buf+8))->b  = one_to_two_bpp[*p++];
  41.       ((struct { int a:4,  b:14; } *) (buf+10))->b = one_to_two_bpp[*p++];
  42.       ((struct { int a:18, b:14; } *) (buf+10))->b = one_to_two_bpp[*p++];
  43.       nbuf = (void *) nbuf + 14;
  44.       
  45. #else
  46.       unsigned long a, b, c;
  47.  
  48.       /* NOTE: This assumes a big-endian CPU! */
  49.       a = one_to_two_bpp[*p++] << 18;
  50.       b = one_to_two_bpp[*p++] << 4;
  51.       c = one_to_two_bpp[*p++];
  52.       *nbuf++ = a | b | (c >> 10);
  53.       a = one_to_two_bpp[*p++] << 8;
  54.       b = one_to_two_bpp[*p++];
  55.       *nbuf++ = (c << 22) | a | (b >> 6);
  56.       a = one_to_two_bpp[*p++] << 12;
  57.       c = one_to_two_bpp[*p++];
  58.       *nbuf++ = (b << 26) | a | (c >> 2);
  59.       a = one_to_two_bpp[*p++];
  60.       *((unsigned short *) nbuf)++ = a | (c << 14);
  61. #endif
  62.     }
  63.     }
  64. }
  65. #else
  66.  
  67. /* Define the Reg type. */
  68. /* Assumes big endian: */
  69. typedef union {
  70.   struct {
  71.     char filler1, filler2;
  72.     unsigned char hi;
  73.     unsigned char c;
  74.   } c;
  75.   struct {
  76.     unsigned short filler;
  77.     unsigned short s;
  78.   } s;
  79.   unsigned long l;
  80. } Reg;
  81.  
  82. void
  83. apple_to_next (const unsigned char *a2buf, unsigned char nextbuf[192][72],
  84.            int first_row, int height)
  85. {
  86.   const unsigned int *row_base = row_to_addr + first_row;
  87.   unsigned long *nbuf = (unsigned long *) &nextbuf[first_row][0];
  88.   const unsigned char *p;
  89.   register short rows_left, n;
  90.  
  91.   /* NOTE: This assumes a big-endian CPU! */
  92.  
  93.   for (rows_left = height - 1; rows_left >= 0; rows_left--)
  94.     {
  95.       Reg a2bits;
  96.       unsigned long a, b, c;
  97.  
  98. #define NEXT_A2BITS a2bits.s.s &= 0x7F; a2bits.s.s <<= 7; a2bits.c.c = *p++
  99.  
  100.  
  101.       p = a2buf + *row_base++;
  102.  
  103.       /* Left edge - 5 bytes */
  104.  
  105.       /* Create the first long and ship it out. */
  106.       a2bits.l = *p++;
  107.       a = color_one_to_two_bpp_even[a2bits.l] << 24;
  108.       NEXT_A2BITS;
  109.       b = color_one_to_two_bpp_odd[a2bits.l] << 10;
  110.       NEXT_A2BITS;
  111.       c = color_one_to_two_bpp_even[a2bits.l];
  112.       *nbuf++ = a | b | (c >> 4);
  113.       
  114.       /* Create the second long and ship it out. */
  115.       NEXT_A2BITS;
  116.       a = color_one_to_two_bpp_odd[a2bits.l] << 14;
  117.       NEXT_A2BITS;
  118.       b = color_one_to_two_bpp_even[a2bits.l];
  119.       *nbuf++ = (c << 28) | a | b;
  120.  
  121.       /* Middle - 32 bytes */
  122.       for (n = 1; n >= 0; n--)
  123.     {
  124.       NEXT_A2BITS;
  125.       a = color_one_to_two_bpp_odd[a2bits.l] << 18;
  126.       NEXT_A2BITS;
  127.       b = color_one_to_two_bpp_even[a2bits.l] << 4;
  128.       NEXT_A2BITS;
  129.       c = color_one_to_two_bpp_odd[a2bits.l];
  130.       *nbuf++ = a | b | (c >> 10);
  131.  
  132.       NEXT_A2BITS;
  133.       a = color_one_to_two_bpp_even[a2bits.l] << 8;
  134.       NEXT_A2BITS;
  135.       b = color_one_to_two_bpp_odd[a2bits.l];
  136.       *nbuf++ = (c << 22) | a | (b >> 6);
  137.  
  138.       NEXT_A2BITS;
  139.       a = color_one_to_two_bpp_even[a2bits.l] << 12;
  140.       NEXT_A2BITS;
  141.       c = color_one_to_two_bpp_odd[a2bits.l];
  142.       *nbuf++ = (b << 26) | a | (c >> 2);
  143.  
  144.       NEXT_A2BITS;
  145.       a = color_one_to_two_bpp_even[a2bits.l] << 16;
  146.       NEXT_A2BITS;
  147.       a |= color_one_to_two_bpp_odd[a2bits.l] << 2;
  148.       NEXT_A2BITS;
  149.       b = color_one_to_two_bpp_even[a2bits.l];
  150.       *nbuf++ = (c << 30) | a | (b >> 12);
  151.  
  152.       NEXT_A2BITS;
  153.       a = color_one_to_two_bpp_odd[a2bits.l] << 6;
  154.       NEXT_A2BITS;
  155.       c = color_one_to_two_bpp_even[a2bits.l];
  156.       *nbuf++ = (b << 20) | a | (c >> 8);
  157.  
  158.       NEXT_A2BITS;
  159.       a = color_one_to_two_bpp_odd[a2bits.l] << 10;
  160.       NEXT_A2BITS;
  161.       b = color_one_to_two_bpp_even[a2bits.l];
  162.       *nbuf++ = (c << 24) | a | (b >> 4);
  163.  
  164.       NEXT_A2BITS;
  165.       a = color_one_to_two_bpp_odd[a2bits.l] << 14;
  166.       NEXT_A2BITS;
  167.       c = color_one_to_two_bpp_even[a2bits.l];
  168.       *nbuf++ = (b << 28) | a | c;
  169.     }
  170.  
  171.       /* Right edge - three bytes. */
  172.       NEXT_A2BITS;
  173.       a = color_one_to_two_bpp_odd[a2bits.l] << 18;
  174.       NEXT_A2BITS;
  175.       b = color_one_to_two_bpp_even[a2bits.l] << 4;
  176.       NEXT_A2BITS;
  177.       c = color_one_to_two_bpp_odd[a2bits.l];
  178.       *nbuf++ = a | b | (c >> 10);
  179.  
  180.       /* Handle trailing stuff. */
  181.       a2bits.s.s &= 0x7F; a2bits.s.s <<= 7;
  182.       *nbuf++ = (c << 22) | (color_one_to_two_bpp_even[a2bits.l] << 8);
  183.     }
  184. }
  185. #endif
  186.  
  187. /* Compares 40 bytes, returning TRUE iff they are equal, FALSE otherwise. */
  188. /* Requires p1, p2 refer to long-addressable addresses.                   */
  189.  
  190. static inline int
  191. equal40bytes (const unsigned char *p1, const unsigned char *p2)
  192. {
  193.   const unsigned long *l1 = (const unsigned long *) p1;
  194.   const unsigned long *l2 = (const unsigned long *) p2;
  195.  
  196.   return (   (*l1++ == *l2++) && (*l1++ == *l2++) && (*l1++ == *l2++)
  197.       && (*l1++ == *l2++) && (*l1++ == *l2++) && (*l1++ == *l2++)
  198.       && (*l1++ == *l2++) && (*l1++ == *l2++) && (*l1++ == *l2++)
  199.       && (*l1++ == *l2++));
  200. }
  201.  
  202.  
  203. /* Finds the areas of the screens that differ in scr1 and scr2.  It breaks the
  204.  * screens into 12 16-row sections.  If any two bytes differ in any section,
  205.  * changed[section number] is set to TRUE, otherwise FALSE.
  206.  * Returns FALSE iff scr1 and scr2 are identical screens.
  207.  */
  208.  
  209. int
  210. find_changed_areas (const unsigned char *scr1, const unsigned char *scr2,
  211.             unsigned char changed[192/16])
  212. {
  213.   const unsigned int *rta, *rta_base;
  214.   short base;
  215.   short i;
  216.   int diff = FALSE;
  217.   unsigned char *ch;
  218.  
  219.   /* Zero all the changed flags. */
  220.   /* FIXME - zero as longs?  Is that safe? */
  221.   for (i = (192 / 16) - 1, ch = &changed[0]; i >= 0; i--)
  222.     *ch++ = FALSE;
  223.  
  224. #if 0
  225.   /* Try each 16 row section.  As soon as we hit a difference, go to next. */
  226.   rta_base = row_to_addr + 192 - 16;
  227.   for (base = 11; base >= 0; rta_base -= 16, base--)
  228.     for (i = 15, rta = rta_base; i >= 0; rta++, i--)
  229.       if (!equal40bytes (scr1 + *rta, scr2 + *rta))
  230.         {
  231.           changed[base] = diff = TRUE;
  232.           break;
  233.         }
  234. #else
  235.   /* Try each 16 row section.  As soon as we hit a difference, go to next. */
  236.   rta_base = row_to_addr + 192 - 16;
  237.   for (base = 11; base >= 0; rta_base -= 16, base--)
  238.     for (i = 15, rta = rta_base; i >= 0; rta++, i--)
  239.       if (!equal40bytes (scr1 + *rta, scr2 + *rta))
  240.         {
  241.           changed[base] = diff = TRUE;
  242.           break;
  243.         }
  244. #endif
  245.  
  246. #if 0  /* Old code. */
  247.   /* Try each 16 row section.  As soon as we hit a difference, go to next. */
  248.   for (base = 192 - 16; base >= 0; base -= 16)
  249.     for (i = 15, rta = row_to_addr + base; i != -1; rta++, i--)
  250.       if (cmp40bytes (scr1 + *rta, scr2 + *rta) >= 0)
  251.     {
  252.       changed[base / 16] = diff = TRUE;
  253.       break;
  254.     }
  255. #endif
  256.  
  257.  
  258.   return diff;
  259. }
  260.  
  261.  
  262. static inline void
  263. copy40bytes (const unsigned char *src, unsigned char *dst)
  264. {
  265.   const unsigned long *s = (const unsigned long *) src;
  266.   unsigned long *d = (unsigned long *) dst;
  267.  
  268.   *d++ = *s++;
  269.   *d++ = *s++;
  270.   *d++ = *s++;
  271.   *d++ = *s++;
  272.   *d++ = *s++;
  273.   *d++ = *s++;
  274.   *d++ = *s++;
  275.   *d++ = *s++;
  276.   *d++ = *s++;
  277.   *d   = *s;
  278. }
  279.  
  280.  
  281. void
  282. copy_changed_areas (const unsigned char *src, unsigned char *dst,
  283.             const unsigned char changed[192/16])
  284. {
  285.   short i;
  286.   long base;
  287.   const unsigned int *rta;
  288.   const unsigned char *ch = &changed[192/16];
  289.  
  290.   for (base = 192 - 16; base >= 0; base -= 16)
  291.     if (*--ch)
  292.       for (i = 15, rta = row_to_addr + base; i >= 0; rta++, i--)
  293. #if 0
  294.     copy40bytes (src + *rta, dst + *rta);
  295. #else   /* gcc 2 does Good Things with memcpy. */
  296.     memcpy ((long *) (dst + *rta), (long *) (src + *rta), 40);
  297. #endif
  298. }
  299.